package com.tywj.lib.net.retrofit.model

import com.tywj.lib.core.common.util.LogUtil
import com.tywj.lib.net.retrofit.callback.BaseCallback
import okhttp3.MediaType
import okhttp3.RequestBody
import okio.*

/**
 * <pre>
 *     author : June Yang
 *     time   : 2020/5/8
 *     desc   : 请求body，封装了显示上传进度的功能
 *     version: 1.0.0
 * </pre>
 */
class ProgressRequestBody(
    private val requestBody: RequestBody,
    private var callback: BaseCallback<*>?
) : RequestBody() {

    override fun contentType(): MediaType? = requestBody.contentType()

    override fun contentLength(): Long {
        try {
            return requestBody.contentLength()
        } catch (e: Exception) {
            LogUtil.printStackTrace(e)
            return -1
        }
    }

    override fun writeTo(sink: BufferedSink) {
        val countingSink = CountingSink(sink, contentLength(), callback)
        val bufferedSink = Okio.buffer(countingSink)
        requestBody.writeTo(bufferedSink)
        bufferedSink.flush()
    }

    private class CountingSink<T>(delegate: Sink, length: Long, val callback: BaseCallback<T>?) :
        ForwardingSink(delegate) {
        private val progress = Progress()

        init {
            progress.totalSize = length
        }

        override fun write(source: Buffer, byteCount: Long) {
            super.write(source, byteCount)

            progress.changeProgress(byteCount) {
                callback?.uploadProgress(it.currentSize, it.totalSize, it.fraction, it.speed)
            }
        }
    }
}